package com.fenfen.novel.utils;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Environment;
import android.provider.Settings;
import android.support.annotation.AttrRes;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Toast;
import android.widget.ProgressBar;

import com.fenfen.novel.R;
import com.fenfen.novel.service.NightMaskService;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class CommonUtil {
  private static final String DATE_FORMAT = "yyyy-MM-dd";
  private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
  private static final String TIME_FORMAT = "HH:mm:ss";
  public static final int DOWN_THREAD_NUM = 3;
  public static final String DOWN_DIR_DEFAULT = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();

  public static String SEARCH_KEY = "search";
  public static String BASE_URL = "http://192.168.2.181:5000/";
  public static String PRE_COVER_URL = "http://www.69shu.com";

  public static final int FIRST_PAGE = 1;

  public static int LOADING = 1;
  public static int NOT_LOADING = 2;

  public static int PAGE_SIZE = 100;

  public static int NONE_INT_DATA = -1;
  public static int ZERO_INT_DATA = 0;

  public static int LOAD_MORE_ITEM = 5;

  public static int TEXT_SIZE_MIN = 14; //sp
  public static int TEXT_SIZE_DEFAULT = 18; //sp
  public static int TEXT_SIZE_MAX = 36; //sp

  public static final int CHAPTER_BRIGHTNESS_SHOW_DEFAULT = 50;

  public static boolean isNetworkReachable(Context mContext) {
    ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo info = cm.getActiveNetworkInfo();
    return info != null && info.isConnected();
  }

  public static String getCurrentHourMinutes() {
    Calendar c = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
    return sdf.format(c.getTime());
  }

  public static Date getDateTime(String timeStr) {
    if (TextUtils.isEmpty(timeStr)) {
      return null;
    }
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT);
    try {
      return sdf.parse(timeStr);
    } catch (ParseException e) {
      e.printStackTrace();
      return null;
    }
  }

  public static String getDateTimeStr(Date date) {
    if (date == null) {
      return null;
    }
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT);
    return sdf.format(date);
  }

  public interface NovelListType {
    byte TYPE_NOVEL_TOP = 1; //排行榜
    byte TYPE_NOVEL_CATEGORY = 2; //分类
    byte TYPE_NOVEL_READED = 3; //已阅读
    byte TYPE_NOVEL_SEARCH = 4; //搜索
  }

  public interface NovelTopType {
    byte ALL = 1;  //总排行榜
    byte ALLCLICK = 2; //总点击榜
    byte MONTHCLICK = 3;  //月点击榜
    byte WEEKCLICK = 4;  //周点击榜
    byte DAYCLICK = 5;  //日点击榜
    byte GOODNUM = 6;  //总收藏榜
    byte SIZE = 7;  //数字排行
    byte NEWHOST = 8; //新书排行
    byte NEWEST = 9; //最新入库
    byte DEFAULT = 10; //默认
    byte WANBEN_ALLCLICK = 10; //[完本]总点击榜
    byte WANBEN_MONTHCLICK = 11; //[完本]月点击榜
    byte WANBEN_WEEKCLICK = 12; //[完本]周点击榜
    byte WANBEN_SIZE = 13; //[完本]数字排行
    byte WANBEN_NEWEST = 14; //[完本]最新入库

  }

  public static byte[] TOPTYPE = new byte[]{
      NovelTopType.WANBEN_ALLCLICK,
      NovelTopType.WANBEN_MONTHCLICK,
      NovelTopType.WANBEN_WEEKCLICK,
      NovelTopType.WANBEN_SIZE,
      NovelTopType.WANBEN_NEWEST,

      NovelTopType.ALL,
      NovelTopType.ALLCLICK,
      NovelTopType.MONTHCLICK,
      NovelTopType.WEEKCLICK,
      NovelTopType.DAYCLICK,
      NovelTopType.GOODNUM,
      NovelTopType.SIZE,
      NovelTopType.NEWHOST
  };

  public interface DATA_STATUS {
    byte NOT_START = 1; //未开始
    byte REQUEST = 2;   //正在请求
    byte NO_DATA = 3;   //无数据返回
    byte SUCCESS = 4;   //请求数据成功
    byte FAIL = 5;      //请求数据失败
  }

  public interface DB_DATA_STATUS {
    byte NEWEST = 1; //最新的
    byte UPDATE = 2; //有更新
  }

  public interface DOWN_STATUS {
    String NO_RESOURCE = "no_resource"; //无资源下载[服务器]
    String SUCCESS = "success"; //可以下载[服务器、阅读记录]
    String DOWNING = "downing"; //正在下载[服务器、阅读记录]
    String NOT_DOWN = "not_down"; //未下载[阅读记录]
    String DEFAULT = NOT_DOWN; //默认[阅读记录]
  }

  public static int[] THEME_LIGHT_COLORS = new int[]{
      R.style.AppTheme_Light,
      R.style.AppTheme_Light_Red,
      R.style.AppTheme_Light_Pink,
      R.style.AppTheme_Light_Purple,
      R.style.AppTheme_Light_Green,
      R.style.AppTheme_Light_Orange,
      R.style.AppTheme_Light_Brown,
      R.style.AppTheme_Light_Cyan
  };

  public static int[] THEME_DARK_COLORS = new int[]{
      R.style.AppTheme_Dark,
      R.style.AppTheme_Dark_Red,
      R.style.AppTheme_Dark_Pink,
      R.style.AppTheme_Dark_Purple,
      R.style.AppTheme_Dark_Green,
      R.style.AppTheme_Dark_Orange,
      R.style.AppTheme_Dark_Brown,
      R.style.AppTheme_Dark_Cyan
  };

  /**
   * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
   */
  public static float dip2px(Context context, float dpValue) {
    final float scale = context.getResources().getDisplayMetrics().density;
    return (dpValue * scale + 0.5f);
  }

  /**
   * 获取虚拟按键栏高度
   *
   * @param context
   * @return
   */
  public static int getNavigationBarHeight(Context context) {
    int result = 0;
    Log.d("isShow", "hasNavBar(context)=" + hasNavigationBar(context));
    if (hasNavigationBar(context)) {
      Resources res = context.getResources();
      int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
      if (resourceId > 0) {
        result = res.getDimensionPixelSize(resourceId);
      }
    }
    return result;
  }

  /**
   * 检查是否存在虚拟按键栏
   *
   * @param context
   * @return
   */
  private static boolean hasNavBar(Context context) {
    Resources res = context.getResources();
    int resourceId = res.getIdentifier("config_showNavigationBar", "bool", "android");
    if (resourceId != 0) {
      boolean hasNav = res.getBoolean(resourceId);
      // check override flag
      if (hasNav) {
        String sNavBarOverride = getNavBarOverride();
        if ("1".equals(sNavBarOverride)) {
          hasNav = false;
        } else if ("0".equals(sNavBarOverride)) {
          hasNav = true;
        }
        return hasNav;
      }
    } // fallback
    return !ViewConfiguration.get(context).hasPermanentMenuKey() && !KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
  }

  public static boolean hasNavigationBar(Context context) {
    Point appUsableSize = getAppUsableScreenSize(context);
    Point realScreenSize = getRealScreenSize(context);

    // navigation bar on the right
    if (appUsableSize.x < realScreenSize.x || appUsableSize.y < realScreenSize.y) {
      return true;
    }

    // navigation bar is not present
    return false;
  }

  public static Point getAppUsableScreenSize(Context context) {
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = windowManager.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    return size;
  }

  public static Point getRealScreenSize(Context context) {
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = windowManager.getDefaultDisplay();
    Point size = new Point();

    if (Build.VERSION.SDK_INT >= 17) {
      display.getRealSize(size);
    } else if (Build.VERSION.SDK_INT >= 14) {
      try {
        size.x = (Integer) Display.class.getMethod("getRawWidth").invoke(display);
        size.y = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
      } catch (IllegalAccessException e) {
      } catch (InvocationTargetException e) {
      } catch (NoSuchMethodException e) {
      }
    }
    return size;
  }

  /**
   * 判断虚拟按键栏是否重写
   *
   * @return
   */
  private static String getNavBarOverride() {
    String sNavBarOverride = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      try {
        Class c = Class.forName("android.os.SystemProperties");
        Method m = c.getDeclaredMethod("get", String.class);
        m.setAccessible(true);
        sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys");
      } catch (Throwable e) {
      }
    }
    return sNavBarOverride;
  }

//  public static int getStatusBarHeight(AppCompatActivity context) {
//    Rect rectangle = new Rect();
//    Window window = context.getWindow();
//    window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
//    int statusBarHeight = rectangle.top;
//    int contentViewTop =
//        window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
//    int titleBarHeight = statusBarHeight - contentViewTop;
//    return titleBarHeight;
//  }

  public static int getStatusBarHeight(Context context) {
    int result = 0;
    int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
      result = context.getResources().getDimensionPixelSize(resourceId);
    }
    return result;
  }

  public static float px2Sp(Context context, float px) {
    float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
    return px / scaledDensity;
  }

  public static void changeAppBrightness(Context context, int brightness) {
    Window window = ((Activity) context).getWindow();
    WindowManager.LayoutParams lp = window.getAttributes();
    if (brightness == -1) {
      lp.screenBrightness = lp.buttonBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
    } else {
      lp.screenBrightness = lp.buttonBrightness = (brightness <= 0 ? 1 : brightness) / 255f;
    }
    window.setAttributes(lp);
  }

  public static int getCurrentLight(Context context) throws Settings.SettingNotFoundException {
    int savedMode = SharedPrefsUtils.getInstance(context).getChapterBrightnessMode();
    return savedMode == Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL ?
        SharedPrefsUtils.getInstance(context).getChapterBrightness() :
        CommonUtil.NONE_INT_DATA;
  }

  public static void showToast(Context context, int titleResId) {
    Toast.makeText(context, titleResId, Toast.LENGTH_LONG).show();
  }

  public static void showToast(Context context, String title) {
    Toast.makeText(context, title, Toast.LENGTH_LONG).show();
  }

  public static void showSnack(View v, int titleResId) {
    showSnack(v, v.getContext().getString(titleResId));
  }

  public static void showSnack(View v, String title) {
    Snackbar.make(v, title, Snackbar.LENGTH_LONG).show();
  }

  public static void showSnackRetry(View v, String title, View.OnClickListener clickListener) {
    showSnackBtn(v, title, R.string.retry, clickListener);
  }

  public static void showSnackRetry(View v, int titleResId, View.OnClickListener clickListener) {
    showSnackRetry(v, v.getContext().getString(titleResId), clickListener);
  }

  public static void showSnackBtn(View v, String title, int btnStrResId, View.OnClickListener clickListener) {
    Snackbar.make(v, title, Snackbar.LENGTH_LONG).setAction(btnStrResId, clickListener).show();
  }

  public static void showSnackBtn(View v, String title, String btnStr, View.OnClickListener clickListener) {
    Snackbar.make(v, title, Snackbar.LENGTH_LONG).setAction(btnStr, clickListener).show();
  }

  public interface CallbackListener {
    void onResponse();

    void onFailure();
  }

  public static int getDevicePxWidth() {
    return Resources.getSystem().getDisplayMetrics().widthPixels;
  }

  // 隐藏系统键盘
  public static void hideSoftInputMethod(Context context, EditText ed) {
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(ed.getWindowToken(), 0);
  }

  public static void removeNightMask(Context context) {
    Intent service = new Intent(context, NightMaskService.class);
    context.stopService(service);
  }

  public static void addNightMask(Context context) {
    Intent service = new Intent(context, NightMaskService.class);
    context.startService(service);
  }

  public static String convertFileSize(long size) {
    long kb = 1024;
    long mb = kb * 1024;
    long gb = mb * 1024;

    if (size >= gb) {
      return String.format("%.1fG", (float) size / gb);
    } else if (size >= mb) {
      float f = (float) size / mb;
      return String.format(f > 100 ? "%.0f M" : "%.1fM", f);
    } else if (size >= kb) {
      float f = (float) size / kb;
      return String.format(f > 100 ? "%.0f K" : "%.1fK", f);
    } else
      return String.format("%dB", size);
  }

  public static String getNovelFilePath(Context context, int novelId) {
    String path = SharedPrefsUtils.getInstance(context).getDownloadDir();
    File dir = new File(path);
    if (!dir.exists()) {
      dir.mkdirs();
    }
    String filePath = dir.getPath() + File.separator + novelId + ".txt";
    return filePath;
  }

  public static boolean isNovelFileExist(Context context, int novelId) {
    String filePath = getNovelFilePath(context, novelId);
    return new File(filePath).exists();
  }
  public static int getThemeId(boolean isNight, int themeColorId, Context context) {
    int index = 0;
    if (themeColorId != index) {
      int[] colors = context.getResources().getIntArray(R.array.colors_material);
      final int size = colors.length;
      for (int i = 0; i < size; i++) {
        if (colors[i] == themeColorId) {
          index = i;
          break;
        }
      }
    }
    if (isNight) {
      return THEME_DARK_COLORS[index];
    } else {
      return THEME_LIGHT_COLORS[index];
    }
  }

  public static int resolveColor(Context context, @AttrRes int attr) {
    return resolveColor(context, attr, 0);
  }

  public static int resolveColor(Context context, @AttrRes int attr, int fallback) {
    TypedArray a = context.getTheme().obtainStyledAttributes(new int[]{attr});
    try {
      return a.getColor(0, fallback);
    } finally {
      a.recycle();
    }
  }

  public static void filterProgressColor(Context context, ProgressBar loadingProgress) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
      Drawable indDraw = loadingProgress.getIndeterminateDrawable();
      if (indDraw != null) {
        filterDrawableColor(context, indDraw, R.attr.colorPrimary);
        loadingProgress.setIndeterminateDrawable(indDraw);
      }
    }
  }

  public static void filterDrawableColor(Context context, Drawable drawable, int attrId) {
    filterDrawableColor(context, drawable, attrId, PorterDuff.Mode.SRC_IN);
  }

  public static void filterDrawableColor(Context context, Drawable drawable, int attrId, PorterDuff.Mode mode) {
    drawable.setColorFilter(CommonUtil.resolveColor(context, attrId), mode);
  }
}
